﻿/********************************************************/
/* For 基于.NET的开发技术 课程设计                      */
/*                    学生选课系统                      */
/*author    ：  吴慧文                                  */
/*time      ：  2009年11月8日                           */
/*版本      ：  1.0                                     */
/*文件名    ：  Program.cs                              */
/********************************************************/
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.Serialization;
using System.IO;
using System.Runtime.Serialization.Formatters.Binary;

namespace CMS
{
    class Program
    {
        static string username = "admin";
        static string psw = "123456";

        static Students students = new Students();
        static Teachers teachers = new Teachers();
        static Courses courses = new Courses();

        static Student theStudent = null;
        static Teacher theTeacher = null;

        //序列化
        static void Serialize()
        {
            //序列化students。。。。。。。。。。
            IFormatter formatter1 = new BinaryFormatter();
            Stream stream1 = new FileStream("Students.bin", FileMode.Create, FileAccess.Write, FileShare.None);
            formatter1.Serialize(stream1, students);
            stream1.Close();

            //序列化teachers。。。。。。。。。。
            IFormatter formatter2 = new BinaryFormatter();
            Stream stream2 = new FileStream("Teachers.bin", FileMode.Create, FileAccess.Write, FileShare.None);
            formatter2.Serialize(stream2, teachers);
            stream2.Close();

            //序列化courses
            IFormatter formatter3 = new BinaryFormatter();
            Stream stream3 = new FileStream("Courses.bin", FileMode.Create, FileAccess.Write, FileShare.None);
            formatter3.Serialize(stream3, courses);
            stream3.Close();
        }

        //反序列化
        static void Deserialize()
        {
            Stream stream1 = new FileStream("Students.bin", FileMode.Open, FileAccess.Read, FileShare.Read);
            try
            {
                //反序列化Students。。。。。。。。。。。
                IFormatter formatter1 = new BinaryFormatter();
                students = (Students)formatter1.Deserialize(stream1);
                stream1.Close();
            }
            catch (SerializationException e)
            {
                Console.WriteLine("Failed to deserialize. Reason: " + e.Message);
            }
            finally
            {
                stream1.Close();
            }

            Stream stream2 = new FileStream("Teachers.bin", FileMode.Open, FileAccess.Read, FileShare.Read);
            try
            {

                //反序列化Teachers。。。。。。。。。。。。
                IFormatter formatter2 = new BinaryFormatter();
                teachers = (Teachers)formatter2.Deserialize(stream2);
                stream2.Close();
            }
            catch (SerializationException e)
            {
                Console.WriteLine("Failed to deserialize. Reason: " + e.Message);
            }
            finally
            {
                stream2.Close();
            }

            Stream stream3 = new FileStream("Courses.bin", FileMode.Open, FileAccess.Read, FileShare.Read);
            try
            {
                //反序列化Courses。。。。。。。。。。。。。
                IFormatter formatter3 = new BinaryFormatter();
                courses = (Courses)formatter3.Deserialize(stream3);
                stream3.Close();
            }
            catch (SerializationException e)
            {
                Console.WriteLine("Failed to deserialize. Reason: " + e.Message);
            }
            finally
            {
                stream3.Close();
            }
        }

        static void Main(string[] args)
        {
            //首先执行反序列化，初始化系统。。
            Deserialize();

            //身份选择，可以以管理员、学生、教师三种不同的身份进入系统
            int type = 0;
            Console.Write("【选择身份】\n1    管理员\n2    学生\n3    教师\n[请输入]");
            type = Convert.ToInt16(Console.ReadLine());

            //根据用户选择的身份，进行不同的身份验证，并进入不同的操作
            switch (type)
            {
                //管理员
                case 1: 
                    Console.Write("【管理员入口】您选择了管理员入口，请输入用户名和密码\n[用户名]");
                    string user = Console.ReadLine();
                    Console.Write("[密码]");
                    string pass = Console.ReadLine();
                    if (user.Equals(username) && pass.Equals(psw))
                    {
                        Console.WriteLine("【登陆成功】您可以进行相关操作了！");
                        bool cont = true;
                        while (cont)
                        {
                            Program.admin();
                            Console.Write("【继续/退出】您可以选择继续操作或者选择退出系统，退出请输入 quit\n[请输入]");
                            string q = Console.ReadLine();
                            if (q.Equals("quit"))
                                cont = false;
                        }      
                    }
                    else
                    {
                        Console.WriteLine("【登陆失败】用户名或者密码错误！系统将退出，请重新打开系统");
                    }
                    break;
                //学生
                case 2:
                    Console.Write("【学生入口】您选择了学生入口，请输入学号和密码\n[学号]");
                    string sid = Console.ReadLine();
                    Console.Write("[密码]");
                    string spass = Console.ReadLine();

                    if (students["ID:" + sid].Count == 0)
                    {
                        Console.WriteLine("【登陆失败】学号不存在！");
                    }
                    else
                    {
                        if (students["ID:" + sid].ElementAt(0).Pwd.Equals(spass))
                        {
                            theStudent = students["ID:" + sid].ElementAt(0);
                            Console.WriteLine("【登陆成功】您可以进行相关操作了！");
                            bool cont = true;
                            while (cont)
                            {
                                Program.student();
                                Console.Write("【继续/退出】您可以选择继续操作或者选择退出系统，退出请输入 quit\n[请输入]");
                                string q = Console.ReadLine();
                                if (q.Equals("quit"))
                                    cont = false;
                            }
                        }
                        else
                        {
                            Console.WriteLine("【登陆失败】密码错误！系统将退出，请重新打开系统");
                        }

                    }
                    break;
                //教师
                case 3:
                    Console.Write("【教师入口】您选择了教师入口，请输入职工号和密码\n[职工号]");
                    user = Console.ReadLine();
                    Console.Write("[密码]");
                    pass = Console.ReadLine();

                    if (teachers["ID:" + user].Count == 0)
                    {
                        Console.WriteLine("【登陆失败】职工号不存在！");
                    }
                    else
                    {
                        if (teachers["ID:" + user].ElementAt(0).Pwd.Equals(pass))
                        {
                            theTeacher = teachers["ID:" + user].ElementAt(0);
                            Console.WriteLine("【登陆成功】您可以进行相关操作了！");
                            bool cont = true;
                            while (cont)
                            {
                                Program.teacher();
                                Console.Write("【继续/退出】您可以选择继续操作或者选择退出系统，退出请输入 quit\n[请输入]");
                                string q = Console.ReadLine();
                                if (q.Equals("quit"))
                                    cont = false;
                            }
                        }
                        else
                        {
                            Console.WriteLine("【登陆失败】密码错误！系统将退出，请重新打开系统");
                        }

                    }
                    break;
                //错误的选择
                default:
                    Console.WriteLine("【警告】不合法的输入！");
                    break;
            }
            //退出系统之前，序列化，保存相关信息。
            Serialize();
            Console.ReadLine();
            return;
        }

        //管理员相关操作
        static void admin()
        {
            Console.Write("【管理员】\n1 添加学生\n2 删除学生\n3 查看学生信息\n\n");
            Console.Write("4 添加教师\n5 删除教师\n6 查看教师信息\n\n");
            Console.Write("7 添加课程\n8 删除课程\n9 查看课程信息\n\n");
            Console.Write("[请输入]");
            int type = Convert.ToInt16(Console.ReadLine());
            switch (type)
            {
                //添加学生。
                case 1:
                    displayStu();
                    addStu();
                    break;
                //删除学生
                case 2:
                    displayStu();
                    deleteStu();
                    break;
                //查找学生
                case 3:
                    displayStu();
                    searchStu();
                    break;
                //添加教师
                case 4:
                    displayTea();
                    addTea();
                    break;
                //删除教师
                case 5:
                    displayTea();
                    deleteTea();
                    break;
                //查找教师
                case 6:
                    displayTea();
                    searchTea();
                    break;
                //添加课程
                case 7:
                    displayCou();
                    addCou();
                    break;
                //删除课程
                case 8:
                    displayCou();
                    deleteCou();
                    break;
                //查找课程
                case 9:
                    displayCou();
                    searchCou();
                    break;
                default:
                    Console.WriteLine("【警告】不合法的输入！");
                    break;

            }
        }

        //学生相关操作
        static void student()
        {
            Console.Write("【学生】\n1 修改密码\n2 查看课表\n3 查询课程\n4 选择课程\n[请输入]");
            int t = Convert.ToInt16(Console.ReadLine());
            switch (t)
            {
                //修改密码，为求简单，这里的修改密码没有做更多的验证。
                case 1:
                    Console.Write("【修改密码】请输入新密码\n[新密码]");
                    string newPass = Console.ReadLine();
                    theStudent.Pwd = newPass;
                    break;
                //查看课表
                case 2:
                    Console.WriteLine("【查看课表】您的课程信息如下");
                    Console.Write(theStudent.getCoursesInfo());
                    break;
                //查询课程
                case 3:
                    searchCou();
                    break;
                //选择课程
                case 4:
                    Console.Write("【选择课程】请输入课程号\n[课程号]");
                    string cid = Console.ReadLine();
                    if (courses["ID:" + cid].Count == 0)
                    {
                        Console.WriteLine("【选择课程失败】没有对应输入课程号的课程！");
                    }
                    else
                    {
                        Course c = courses["ID:" + cid].ElementAt(0);
                        if (theStudent.addCourse(c))
                            Console.WriteLine("【选择课程成功】");
                        else
                            Console.WriteLine("【选择课程失败】课程上课时间冲突！");
                    }
                    break;
                default:
                    Console.WriteLine("【警告】不合法的输入！");
                    break;


            }
 
        }

        //教师相关操作
        static void teacher()
        {
            Console.Write("【教师】\n1 修改密码\n2 查看课表\n3 查看课程选课学生\n[请输入]");
            int t = Convert.ToInt16(Console.ReadLine());
            switch (t)
            {
                //修改密码，为求简单，这里的修改密码没有做更多的验证。
                case 1:
                    Console.Write("【修改密码】请输入新密码\n[新密码]");
                    string newPass = Console.ReadLine();
                    theTeacher.Pwd = newPass;
                    break;
                //查看课表，查看的是自己任课的课程信息
                case 2:
                    Console.WriteLine("【查看课表】您的课程信息如下");
                    for (int i = 0; i < courses[""].Count; i++)
                    {
                        if(courses[""].ElementAt(i).TheTeacher.Equals(theTeacher))
                        {
                            Console.WriteLine(courses[""].ElementAt(i).toString());
                        }
                    }
                    break;
                //查看选课学生，根据课程号查询到选择该课的学生
                //这里没有做 该课程是否为该教师的课程。只求简单
                //有个弊端就是可以查询任何课程的选课学生。
                case 3:
                    Console.WriteLine("【查看选课学生】请输入课程号\n[课程号]");
                    string cid = Console.ReadLine();
                    if (courses["ID:" + cid].Count == 0)
                    {
                        Console.WriteLine("【失败】没有指定的课程信息！");
                    }
                    else
                    {
                        Console.WriteLine("【成功】选课学生信息如下");
                        for (int i = 0; i < students[""].Count; i++)
                        {
                            if (students[""].ElementAt(i).MyCourses["ID:" + cid].Count != 0)
                            {
                                Console.WriteLine(students[""].ElementAt(i).toStringWithoutPsw());
                            }
                        }
                    }
                    break; 
                //非法的输入。
                default:
                    Console.WriteLine("【警告】不合法的输入！");
                    break;

            }
        }

        //添加学生
        static void addStu()
        {
            Console.Write("【添加学生】请输入相关信息,学号不可以重复\n[学生学号]");
            string sid = Console.ReadLine();
            Console.Write("[学生姓名]");
            string sname = Console.ReadLine();

            //为新注册的学生添加空的课表
            Courses cs = new Courses();
            Student s = new Student(sid, sname, "123456", cs);

            //判断是否重复学号，重复则不添加
            if (students["ID:" + sid].Count != 0)
            {
                Console.WriteLine("【添加学生失败】学号重复！");
            }
            else
            {
                students.addStudent(s);
                Console.WriteLine("【添加学生成功】");
            }  
        }

        //删除学生
        static void deleteStu()
        {
            Console.Write("【删除学生】请输入要删除学生的学号\n[学号]");
            string sid = Console.ReadLine();
            if (students["ID:" + sid].Count == 0)
            {
                Console.WriteLine("【删除学生失败】学号不存在！");
            }
            else
            {
                //删除学生，通过查询某特定学生
                students.deleteStudent(students["ID:" + sid].ElementAt(0));
                Console.WriteLine("【删除学生成功】");
            }
        }

        //查找学生  For  管理员
        static void searchStu()
        {
            Console.Write("【查找学生】不支持模糊查询\n1 按学号查找\n2 按姓名查找\n[输入]");
            int t = Convert.ToInt16(Console.ReadLine());
            switch (t)
            {
                case 1:
                    Console.Write("【按学号】请输入学号\n[学号]");
                    string sid = Console.ReadLine();
                    Console.Write("【查询结果】如下\n");
                    for (int i = 0; i < students["ID:" + sid].Count; i++)
                    {
                        Console.WriteLine(students["ID:" + sid].ElementAt(i).toString());
                    }
                    break;
                case 2:
                    Console.Write("【按姓名】请输入姓名\n[姓名]");
                    string sname = Console.ReadLine();
                    Console.Write("【查询结果】如下\n");
                    for (int i = 0; i < students["NAME:" + sname].Count; i++)
                    {
                        Console.WriteLine(students["NAME:" + sname].ElementAt(i).toString());
                    }
                    break;
                default:
                    Console.WriteLine("【警告】不合法的输入！");
                    break;
            }
        }

        //添加教师
        static void addTea()
        {
            Console.Write("【添加教师】请输入相关信息,职工号不可以重复\n[教师职工号]");
            string tid = Console.ReadLine();
            Console.Write("[教师姓名]");
            string tname = Console.ReadLine();

            Teacher t = new Teacher(tid, tname, "123456");

            //判断是否重复职工号，重复则不添加
            if (teachers["ID:" + tid].Count != 0)
            {
                Console.WriteLine("【添加教师失败】职工号重复！");
            }
            else
            {
                teachers.addTeacher(t);
                Console.WriteLine("【添加教师成功】");
            } 
        }

        //删除教师
        static void deleteTea()
        {
            Console.Write("【删除教师】请输入要删除教师的职工号\n[职工号]");
            string tid = Console.ReadLine();
            if (teachers["ID:" + tid].Count == 0)
            {
                Console.WriteLine("【删除教师失败】职工号不存在！");
            }
            else
            {
                //删除学生，通过查询某特定学生
                teachers.deleteTeacher(teachers["ID:" + tid].ElementAt(0));
                Console.WriteLine("【删除教师成功】");
            }
        }

        //查找教师  For  管理员
        static void searchTea()
        {
            Console.Write("【查找教师】不支持模糊查询\n1 按职工号查找\n2 按姓名查找\n[输入]");
            int t = Convert.ToInt16(Console.ReadLine());
            switch (t)
            {
                case 1:
                    Console.Write("【按职工号】请输入职工号\n[职工号]");
                    string tid = Console.ReadLine();
                    Console.Write("【查询结果】如下\n");
                    for (int i = 0; i < teachers["ID:" + tid].Count; i++)
                    {
                        Console.WriteLine(teachers["ID:" + tid].ElementAt(i).toString());
                    }
                    break;
                case 2:
                    Console.Write("【按姓名】请输入姓名\n[姓名]");
                    string tname = Console.ReadLine();
                    Console.Write("【查询结果】如下\n");
                    for (int i = 0; i < teachers["NAME:" + tname].Count; i++)
                    {
                        Console.WriteLine(teachers["NAME:" + tname].ElementAt(i).toString());
                    }
                    break;
                default:
                    Console.WriteLine("【警告】不合法的输入！");
                    break;
            }
        }

        //添加课程
        static void addCou()
        {
            Console.Write("【添加课程】请输入相关信息,编号不可以重复\n[课程编号]");
            string cid = Console.ReadLine();
            Console.Write("[课程名]");
            string cname = Console.ReadLine();
            Console.Write("[教师职工号]");
            string tid = Console.ReadLine();
            Console.Write("[上课时间（星期几）]");
            int dow = Convert.ToInt16(Console.ReadLine());
            Console.Write("[上课时间（第几大节）]");
            int nod =  Convert.ToInt16(Console.ReadLine());

            if (teachers["ID:" + tid].Count == 0)
            {
                Console.WriteLine("【添加失败】教师职工号不存在！");
                return;
            }

            Course c = new Course(cid, cname, teachers["ID:"+tid].ElementAt(0),dow,nod);

            //判断是否重复职工号，重复则不添加
            if (courses["ID:" + cid].Count != 0)
            {
                Console.WriteLine("【添加失败】课程号重复！");
            }
            else
            {
                courses.addCourse(c);
                Console.WriteLine("【添加课程成功】");
            }
        }

        //删除课程
        static void deleteCou()
        {
            Console.Write("【删除课程】请输入要删除课程的编号\n[编号]");
            string cid = Console.ReadLine();
            if (courses["ID:" + cid].Count == 0)
            {
                Console.WriteLine("【删除课程失败】课程编号不存在！");
            }
            else
            {
                //删除课程，通过查询某特定课程
                courses.deleteCourse(courses["ID:" + cid].ElementAt(0));
                Console.WriteLine("【删除课程成功】");
            }
        }

        //查找课程  For  管理员
        static void searchCou()
        {
            Console.Write("【查找课程】不支持模糊查询\n1 按课程编号查找\n2 按课程名查找");
            Console.Write("\n3 按课程教师名查找\n\n4 按上课星期几查找\n5 按上课节次查找\n6 按上课时间查找\n[请输入]");
            int t = Convert.ToInt16(Console.ReadLine());
            switch (t)
            {
                //按课程编号
                case 1:
                    Console.Write("【按课程编号】请输入课程编号\n[课程编号]");
                    string cid = Console.ReadLine();
                    Console.Write("【查询结果】如下\n");
                    for (int i = 0; i < courses["ID:" + cid].Count; i++)
                    {
                        Console.WriteLine(courses["ID:" + cid].ElementAt(i).toString());
                    }
                    break;
                //按课程名
                case 2:
                    Console.Write("【按课程名】请输入课程名\n[课程名]");
                    string cname = Console.ReadLine();
                    Console.Write("【查询结果】如下\n");
                    for (int i = 0; i < courses["NAME:" + cname].Count; i++)
                    {
                        Console.WriteLine(courses["NAME:" + cname].ElementAt(i).toString());
                    }
                    break;
                //按课程教师名
                case 3:
                    Console.Write("【按课程教师名】请输入课程教师名[课程教师名]");
                    string tname = Console.ReadLine();
                    Console.WriteLine("【查询结果】如下\n");
                    for (int i = 0; i < courses["TEACHER:" + tname].Count; i++)
                    {
                        Console.WriteLine(courses["TEACHER:" + tname].ElementAt(i).toString());
                    }
                    break;
                //按上课星期几
                case 4:
                    Console.Write("【按上课星期几】请输入上课星期几[上课星期几]");
                    int dow = Convert.ToInt16( Console.ReadLine());
                    Console.WriteLine("【查询结果】如下\n");
                    for (int i = 0; i < courses["DAY:" + dow].Count; i++)
                    {
                        Console.WriteLine(courses["DAY:" + dow].ElementAt(i).toString());
                    }
                    break;
                //按上课节次
                case 5:
                    Console.Write("【按上课节次】请输入上课节次[上课节次]");
                    int nod = Convert.ToInt16(Console.ReadLine());
                    Console.WriteLine("【查询结果】如下\n");
                    for (int i = 0; i < courses["NUM:" + nod].Count; i++)
                    {
                        Console.WriteLine(courses["NUM:" + nod].ElementAt(i).toString());
                    }
                    break;
                //按上课时间
                case 6:
                    Console.Write("【按上课时间】请输入上课星期几、上课节次[上课星期几]");
                    dow = Convert.ToInt16(Console.ReadLine());
                    Console.Write("[上课节次]");
                    nod = Convert.ToInt16(Console.ReadLine());
                    Console.WriteLine("【查询结果】如下\n");
                    for (int i = 0; i < courses["DAYANDNUM:" +dow+":"+ nod].Count; i++)
                    {
                        Console.WriteLine(courses["DAYANDNUM:" + dow + ":" + nod].ElementAt(i).toString());
                    }
                    break;
                default:
                    Console.WriteLine("【警告】不合法的输入！");
                    break;
            }
        }

        //显示所有学生信息  只为精简代码
        static void displayStu()
        {   
            Console.WriteLine("##############################################");
            Console.WriteLine("##############所有学生信息一览表##############");
            for (int i = 0; i < students[""].Count; i++)
            {
                Console.WriteLine(students[""].ElementAt(i).toString());
            }
            Console.WriteLine("##############################################");
        }

        //显示所有教师信息  只为精简代码
        static void displayTea()
        {
            Console.WriteLine("##############################################");
            Console.WriteLine("##############所有教师信息一览表##############");
            for (int i = 0; i < teachers[""].Count; i++)
            {
                Console.WriteLine(teachers[""].ElementAt(i).toString());
            }
            Console.WriteLine("##############################################");
        }

        //显示所有课程信息  只为精简代码
        static void displayCou()
        {
            Console.WriteLine("##############################################");
            Console.WriteLine("##############所有课程信息一览表##############");
            for (int i = 0; i < courses[""].Count; i++)
            {
                Console.WriteLine(courses[""].ElementAt(i).toString());
            }
            Console.WriteLine("##############################################");
        }

    }
}
